/*
 * OpenParts
 * A dynamic-loading components framework for GWT
 * Copyright (C) 2011 Christophe Bouthier  [chris{AT}binary-gastronome{DOT}fr]
 *
 * This work is partially based on work I have done at INRIA (http://www.inria.fr) 
 * in the context of the Qualipso European Project (http://qualipso.org/),
 * The work done at INRIA is Copyright (C) 2006-2011 INRIA
 *
 * This work is distributed under the LGPL version 3
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version 3
 * as published by the Free Software Foundation. See the GNU
 * Lesser General Public License in LGPL.txt for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package fr.openparts.OpenParts.test.gwt.dummyPart.client;

import java.util.ArrayList;
import java.util.List;


import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

import fr.openparts.OpenParts.client.OPBinder;
import fr.openparts.OpenParts.client.OPCommandCallback;
import fr.openparts.OpenParts.client.OPMessageFromContainerSlotHandler;
import fr.openparts.OpenParts.client.OPParams;
import fr.openparts.OpenParts.client.OPSlotProxy;
import fr.openparts.OpenParts.client.annotations.OPEventHandler;
import fr.openparts.OpenParts.client.annotations.OPMandatoryParams;
import fr.openparts.OpenParts.client.annotations.OPServiceName;
import fr.openparts.OpenParts.client.annotations.OPViewFactory;

/**
 * Dummy part, to test calls to generated binder.
 * 
 * @author Christophe Bouthier [chris{AT}binary-gastronome{DOT}fr]
 * @creation.date 18 December 2009
 */
@OPServiceName("dummyService")
public final class DummyPart {

    // the magic to test
    public interface DummyPartBinder extends OPBinder<DummyPart> {}
    public static final DummyPartBinder binder = GWT.create(DummyPartBinder.class);

    public int simpleViewFactory = 0; // used to count number of time the simple view factory has been called
    public int mandatoryParamsViewFactory = 0; // used to count number of time the view factory with mandatory params has been called

    public int eventHandlerCalls = 0; // used to count number of time the eventHandler has been called
    public int specificHandlerCalls = 0; // used to count number of time the specific event handler has been called

    private int messageHandlerViewCounter = 0; // used to have different views each time the view factory is called
    public List<Integer> messageHandlerCallsByIndex = new ArrayList<Integer>(); // used to count number of time the message for a specific view has been called
    public List<Integer> embeddedViewAttachHandlerCallsByIndex = new ArrayList<Integer>(); // used to count number of time onEmbeddedViewAttach for a specific view has been called

    public int messageHandler1Calls = 0; // used to test with several message handlers on the same proxy
    public int messageHandler2Calls = 0;
    
    public int embeddedViewAttachHandler1Calls = 0; // used to test with several message handlers on the same proxy
    public int embeddedViewAttachHandler2Calls = 0;
    
    public OPCommandCallback callback; // used to test scheduled message dispatching
    
    public List<OPSlotProxy> slotProxyByIndex = new ArrayList<OPSlotProxy>(); // used to get access to view proxys

    public OPParams params = null; // used to test passing params to event

    /**
     * Launch the binding.
     */
    public final void bind() {
        binder.bindPart(this);
    }

    /**
     * Event handler, called by the event bus when a part send an event on the event bus. Registered as callback for the even bus thanks to the
     * {@link OPEventHandler} annotation.
     * 
     * @param event
     *            the event send. Cannot be null.
     * @param params
     *            the parameters. Can be empty, can be null.
     */
    @OPEventHandler
    public final void receiveEvent(final String event, final OPParams params) {
        ++eventHandlerCalls;
        this.params = params;
    }

    /**
     * Event handler, called by the event bus when a part send specifics events on the event bus. Registered as callback for the even bus thanks to the
     * {@link OPEventHandler} annotation.
     * 
     * @param event
     *            the event send. Cannot be null.
     * @param params
     *            the parameters. Can be empty, can be null.
     */
    @OPEventHandler({ "SPECIFIC_EVENT", "SPECIFIC_EVENT_2" })
    public final void receiveSpecificEvent(final String event, final OPParams params) {
        ++specificHandlerCalls;
    }

    /**
     * View factory
     * 
     * @param params
     *            the initialization parameters for the view
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource", actionName = "dummyAction1")
    public final Widget viewFactorySimple(final OPParams params, final OPSlotProxy proxy) {
        ++simpleViewFactory;
        return new Label("viewFactorySimple");
    }

    /**
     * View factory with mandatory params annotation
     * 
     * @param params
     *            the initialization parameters for the view
     * @param proxy
     *            proxy to the container slot
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource", actionName = "dummyAction2")
    @OPMandatoryParams({ "dummyParam1", "dummyParam2" })
    public final Widget viewFactoryMandatoryParams(final OPParams params, final OPSlotProxy proxy) {
        ++mandatoryParamsViewFactory;
        return new Label("viewFactoryMandatoryParams");
    }

    /**
     * View factory for messages dispatching
     * 
     * @param params
     *            the initialization parameters for the view
     * @param proxy
     *            proxy to the container slot
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource", actionName = "dummyAction3")
    public final Widget viewFactoryMessagesDispatcher(final OPParams params, final OPSlotProxy proxy) {
        messageHandlerCallsByIndex.add(0);
        embeddedViewAttachHandlerCallsByIndex.add(0);
        proxy.addMessageHandler(new DummyHandler(messageHandlerViewCounter));
        slotProxyByIndex.add(proxy);
        ++messageHandlerViewCounter;
        return new Label("viewFactoryMessagesDispatcher");
    }

    /**
     * View factory for messages dispatching with several handlers
     * 
     * @param params
     *            the initialization parameters for the view
     * @param proxy
     *            proxy to the container slot
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource", actionName = "dummyAction4")
    public final Widget viewFactoryDoubleMessagesHandler(final OPParams params, final OPSlotProxy proxy) {
        proxy.addMessageHandler(new OPMessageFromContainerSlotHandler() {
            @Override
            public void handleMessageFromContainerSlot(String message, OPParams params) {
                ++messageHandler1Calls;
            }
            @Override
            public void onEmbeddedViewAttach() {
                ++embeddedViewAttachHandler1Calls;
            }
        });
        proxy.addMessageHandler(new OPMessageFromContainerSlotHandler() {
            @Override
            public void handleMessageFromContainerSlot(String message, OPParams params) {
                ++messageHandler2Calls;
            }
            @Override
            public void onEmbeddedViewAttach() {
                ++embeddedViewAttachHandler2Calls;
            }
        });
        return new Label("viewFactoryDoubleMessagesHandler");
    }

    /**
     * View factory for scheduled message dispatching
     * 
     * @param params
     *            the initialization parameters for the view
     * @param proxy
     *            proxy to the container slot
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource", actionName = "dummyAction5")
    public final Widget viewFactoryScheduledMessagesDispatching(final OPParams params, final OPSlotProxy proxy) {
        proxy.dispatchMessageToContainerSlot("message", null, callback);
        return new Label("viewFactoryScheduledMessagesDispatching");
    }
    
    /**
     * View factory just to have another resource name.
     * 
     * @param params
     *            the initialization parameters for the view
     * @param proxy
     *            proxy to the container slot
     * @return the view
     */
    @OPViewFactory(resourceName = "dummyResource1", actionName = "dummyAction")
    public final Widget viewFactory(final OPParams params, final OPSlotProxy proxy) {
        return new Label("viewFactory");
    }
    
    /**
     * Dummy view class, implementing the message handling method.
     */
    public class DummyHandler implements OPMessageFromContainerSlotHandler {

        private int index = 0;

        /**
         * Constructor, taking the index in parameter.
         * 
         * @param index
         *            the view index
         */
        public DummyHandler(final int index) {
            this.index = index;
        }

        /**
         * Message handler method.
         */
        @Override
        public void handleMessageFromContainerSlot(final String message, final OPParams params) {
            final int count = messageHandlerCallsByIndex.get(index).intValue() + 1;
            messageHandlerCallsByIndex.set(index, count);
        }

        /**
         * Embedded view attachment handler method.
         */
        @Override
        public void onEmbeddedViewAttach() {
            final int count = embeddedViewAttachHandlerCallsByIndex.get(index).intValue() + 1;
            embeddedViewAttachHandlerCallsByIndex.set(index, count);
        }
    }

}
